
package com.jf.cloud.delivery.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.jf.cloud.api.delivery.dto.DeliveryOrderDTO;
import com.jf.cloud.api.delivery.dto.DeliveryOrderItemDTO;
import com.jf.cloud.api.delivery.vo.AreaVO;
import com.jf.cloud.api.delivery.vo.DeliveryInfoVO;
import com.jf.cloud.api.delivery.vo.DeliveryOrderFeignVO;
import com.jf.cloud.api.leaf.dto.SegmentDTO;
import com.jf.cloud.api.leaf.dto.SegmentItemDTO;
import com.jf.cloud.api.leaf.feign.SegmentFeignClient;
import com.jf.cloud.api.user.feign.UserAddrFeignClient;
import com.jf.cloud.common.constant.DistributedIdKey;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.order.constant.DeliveryType;
import com.jf.cloud.common.order.vo.UserAddrVO;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.delivery.mapper.DeliveryOrderItemMapper;
import com.jf.cloud.delivery.mapper.DeliveryOrderMapper;
import com.jf.cloud.delivery.model.DeliveryOrder;
import com.jf.cloud.delivery.model.DeliveryOrderItem;
import com.jf.cloud.delivery.service.DeliveryCompanyService;
import com.jf.cloud.delivery.service.DeliveryOrderService;
import com.jf.cloud.delivery.vo.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单快递信息
 *
 * @author zz
 * @date 2020-12-07 15:10:00
 */
@Service
public class DeliveryOrderServiceImpl implements DeliveryOrderService {

    private static final Logger logger = LoggerFactory.getLogger(DeliveryOrderServiceImpl.class);

    @Autowired
    private DeliveryOrderMapper deliveryOrderMapper;

    @Autowired
    private DeliveryOrderItemMapper deliveryOrderItemMapper;

    @Autowired
    private DeliveryCompanyService deliveryCompanyService;

    @Autowired
    private SegmentFeignClient segmentFeignClient;

    @Autowired
    private UserAddrFeignClient userAddrFeignClient;

    @Override
    public DeliveryOrderVO getByDeliveryOrderId(Long deliveryOrderId) {
        return deliveryOrderMapper.getByDeliveryOrderId(deliveryOrderId);
    }

    @Override
    public List<DeliveryOrderFeignVO> getByDeliveryByOrderId(Long orderId){
        List<DeliveryOrderFeignVO> deliveryOrderList = deliveryOrderMapper.getByDeliveryByOrderId(orderId, null);
        if(CollUtil.isEmpty(deliveryOrderList)) {
            return deliveryOrderList;
        }
        // 只需要查询第一个包裹的物流，其他包裹等用户点击后再查询
        DeliveryOrderFeignVO deliveryOrderFeignVO = deliveryOrderList.get(0);
        // 没有物流信息就不用查询
        if (Objects.isNull(deliveryOrderFeignVO.getDeliveryCompanyId()) || StrUtil.isBlank(deliveryOrderFeignVO.getDeliveryNo())) {
            return deliveryOrderList;
        }
        DeliveryCompanyVO deliveryCompanyVO = deliveryCompanyService.getByDeliveryCompanyId(deliveryOrderFeignVO.getDeliveryCompanyId());
        // 获取物流信息
        DeliveryInfoVO deliveryInfoVO;
        if (deliveryCompanyVO == null) {
            deliveryInfoVO = new DeliveryInfoVO();
            logger.error("物流公司信息查询失败，deliveryCompanyId:{}", deliveryOrderFeignVO.getDeliveryCompanyId());
        } else {
            deliveryOrderFeignVO.setDeliveryName(deliveryCompanyVO.getName());
            deliveryInfoVO = deliveryCompanyService.query(deliveryCompanyVO, deliveryOrderFeignVO.getDeliveryCompanyId(), deliveryOrderFeignVO.getDeliveryNo(), deliveryOrderFeignVO.getConsigneeMobile());
            logger.info("订单物流信息查询完毕： {}", deliveryInfoVO);
        }
        deliveryOrderFeignVO.setDelivery(deliveryInfoVO);
        return deliveryOrderList;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveDeliveryInfo(DeliveryOrderDTO deliveryOrderParam) {
        List<DeliveryOrderItemDTO> selectOrderItems = deliveryOrderParam.getSelectOrderItems();
        // 快递发货
        if (Objects.equals(DeliveryType.DELIVERY.value(), deliveryOrderParam.getDeliveryType())
                || Objects.equals(DeliveryType.NOT_DELIVERY.value(), deliveryOrderParam.getDeliveryType())){
//            ServerResponseEntity<OrderAddrVO> orderAddrRes = orderAddrFeignClient.getOrderAddrByOrderId(orderId);
//            if (orderAddrRes.isFail()) {
//                throw new LuckException(orderAddrRes.getMsg());
//            }
//            OrderAddrVO orderAddrVO = orderAddrRes.getData();
            //校验数量及获取发货的总数
             int prodNumSum = getAllProdNum(selectOrderItems);
            loadOrderDateId(deliveryOrderParam);
            DeliveryOrder deliveryOrder = new DeliveryOrder();
            deliveryOrder.setDeliveryOrderId(deliveryOrderParam.getDeliveryOrderId());
            deliveryOrder.setUserId(deliveryOrderParam.getUserId());
            deliveryOrder.setOrderId(deliveryOrderParam.getOrderId());
            if (Objects.equals(DeliveryType.DELIVERY.value(), deliveryOrderParam.getDeliveryType())){
                //只有快递配送才有物流公司和单号
                logger.info("快递配送，物流公司：{}，单号：{}", deliveryOrderParam.getDeliveryCompanyId(), deliveryOrderParam.getDeliveryNo());
                deliveryOrder.setDeliveryCompanyId(deliveryOrderParam.getDeliveryCompanyId());
                deliveryOrder.setDeliveryNo(deliveryOrderParam.getDeliveryNo());
            }
            deliveryOrder.setCreateTime(new Date());
            deliveryOrder.setStatus(1);
            deliveryOrder.setAllCount(prodNumSum);
            // 保存收件人信息
            deliveryOrder.setConsigneeMobile(deliveryOrderParam.getMobile());
            deliveryOrder.setConsigneeName(deliveryOrderParam.getConsignee());
//            if (Objects.nonNull(orderAddrVO)) {
//                // 保存收件人信息
//                deliveryOrder.setConsigneeMobile(deliveryOrderParam.getMobile());
//                deliveryOrder.setConsigneeName(deliveryOrderParam.getConsignee());
//            }
            deliveryOrder.setDeliveryType(deliveryOrderParam.getDeliveryType());
            //保存订单物流信息
            deliveryOrderMapper.save(deliveryOrder);
            //保存需要添加的关联信息
            if(CollectionUtil.isNotEmpty(deliveryOrderParam.getSelectOrderItems())){
                logger.info("保存订单物流信息，deliveryOrderId：{}", deliveryOrder.getDeliveryOrderId());
                List<DeliveryOrderItem> deliveryOrderItems = new ArrayList<>();
                for (DeliveryOrderItemDTO selectOrderItem : deliveryOrderParam.getSelectOrderItems()) {
                    DeliveryOrderItem deliveryOrderItem = new DeliveryOrderItem();
                    deliveryOrderItem.setDeliveryOrderItemId(selectOrderItem.getOrderItemId());
                    deliveryOrderItem.setDeliveryOrderId(deliveryOrder.getDeliveryOrderId());
                    deliveryOrderItem.setCount(selectOrderItem.getChangeNum());
                    deliveryOrderItem.setSpuName(selectOrderItem.getSpuName());
                    deliveryOrderItem.setImgUrl(selectOrderItem.getPic());
                    deliveryOrderItems.add(deliveryOrderItem);
                }
                deliveryOrderItemMapper.saveBatch(deliveryOrderItems);
            }
        }
    }

    private void loadOrderDateId(DeliveryOrderDTO deliveryOrderParam) {
        int itemSize = deliveryOrderParam.getSelectOrderItems().size();
        List<SegmentItemDTO> segmentItemList = new ArrayList<>();
        segmentItemList.add(new SegmentItemDTO(DistributedIdKey.MALL4CLOUD_DELIVERY_ORDER, 1));
        segmentItemList.add(new SegmentItemDTO(DistributedIdKey.MALL4CLOUD_DELIVERY_ORDER_ITEM, itemSize));

        // 获取订单id列表
        ServerResponseEntity<Map<String, List<Long>>> segmentIdResponse = segmentFeignClient.batchSegmentIdWithDateTime(new SegmentDTO(deliveryOrderParam.getUserId(), segmentItemList));
        if (segmentIdResponse.isFail()) {
            throw new LuckException(segmentIdResponse.getMsg());
        }

        Map<String, List<Long>> map = segmentIdResponse.getData();
        List<Long> orderIds = map.get(DistributedIdKey.MALL4CLOUD_DELIVERY_ORDER);
        List<Long> orderItemIds = map.get(DistributedIdKey.MALL4CLOUD_DELIVERY_ORDER_ITEM);
        if (CollUtil.isNotEmpty(orderIds)) {
            deliveryOrderParam.setDeliveryOrderId(orderIds.get(0));
        }
        for (DeliveryOrderItemDTO selectOrderItem : deliveryOrderParam.getSelectOrderItems()) {
            selectOrderItem.setOrderItemId(orderItemIds.remove(0));
        }
    }

    @Override
    public List<DeliveryOrderVO> listDetailDelivery(Long orderId) {
        return deliveryOrderItemMapper.listDetailDelivery(orderId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderDeliveries(List<DeliveryOrderDTO> list) {
        for (DeliveryOrderDTO deliveryOrderDTO : list) {
            DeliveryOrder deliveryOrder = new DeliveryOrder();
            deliveryOrder.setDeliveryOrderId(deliveryOrderDTO.getDeliveryOrderId());
            deliveryOrder.setDeliveryCompanyId(deliveryOrderDTO.getDeliveryCompanyId());
            deliveryOrder.setDeliveryNo(deliveryOrderDTO.getDeliveryNo());
            deliveryOrderMapper.update(deliveryOrder);
        }
//        deliveryOrderMapper.updateBatch(list);
    }

    @Override
    public DeliveryOrderFeignVO deliveryOrderItemInfo(Long deliveryOrderId) {
        List<DeliveryOrderFeignVO> deliveryOrderList = deliveryOrderMapper.getByDeliveryByOrderId(null, deliveryOrderId);
        if (CollUtil.isEmpty(deliveryOrderList)) {
            throw new LuckException("包裹信息不存在，请刷新后重试");
        }
        // 只需要查询第一个包裹的物流，其他包裹等用户点击后再查询
        DeliveryOrderFeignVO deliveryOrderFeignVO = deliveryOrderList.get(0);
        if (Objects.nonNull(deliveryOrderFeignVO) && Objects.nonNull(deliveryOrderFeignVO.getDeliveryNo())){
            // 查询交易单
            DeliveryCompanyVO deliveryCompanyVO = deliveryCompanyService.getByDeliveryCompanyId(deliveryOrderFeignVO.getDeliveryCompanyId());

            // 获取物流信息
            deliveryOrderFeignVO.setDeliveryName(deliveryCompanyVO.getName());
            DeliveryInfoVO deliveryInfoVO = deliveryCompanyService.query(deliveryCompanyVO, deliveryOrderFeignVO.getDeliveryCompanyId(), deliveryOrderFeignVO.getDeliveryNo(), deliveryOrderFeignVO.getConsigneeMobile());
            deliveryOrderFeignVO.setDelivery(deliveryInfoVO);
        }
        return deliveryOrderFeignVO;
    }

    @Override
    public List<DeliveryOrderFeignVO> listDeliveryCountByOrderId(List<Long> orderIds) {
        if (CollUtil.isEmpty(orderIds)) {
            return new ArrayList<>();
        }
        return deliveryOrderMapper.listDeliveryCountByOrderId(orderIds);
    }

    private int getAllProdNum(List<DeliveryOrderItemDTO> selectOrderItems) {
        //获取发货总数
        int prodNumSum = 0;
        for (DeliveryOrderItemDTO selectOrderItem : selectOrderItems) {
            prodNumSum += selectOrderItem.getChangeNum();
        }
        return prodNumSum;
    }

    @Override
    public void save(DeliveryOrder deliveryOrder) {
        deliveryOrderMapper.save(deliveryOrder);
    }

    @Override
    public void update(DeliveryOrder deliveryOrder) {
        deliveryOrderMapper.update(deliveryOrder);
    }

    @Override
    public void deleteById(Long deliveryOrderId) {
        deliveryOrderMapper.deleteById(deliveryOrderId);
    }

    @Override
    public Boolean checkAddr(TransportVO transportVO, Long userId, Long addrId){
        UserAddrVO userAddrVO;
        if(addrId != null && addrId != 0){
            userAddrVO = userAddrFeignClient.getUserAddrByAddrId(addrId).getData();
        }else {
            userAddrVO = userAddrFeignClient.getUserAddrByUserId(userId).getData();
        }
        if(transportVO.getIsFreeFee() == 1 || userAddrVO == null){
            return true;
        }else{
            List<AreaVO> areaList = new ArrayList<>();
            List<TransfeeVO> transFees = transportVO.getTransFees();
            if(!transFees.isEmpty()){
                for (TransfeeVO transFee : transFees) {
                    areaList.addAll(transFee.getCityList());
                }
            }
            Map<Long, List<AreaVO>> areaMap = areaList.stream().collect(Collectors.groupingBy(AreaVO::getAreaId));
            if(areaMap.containsKey(userAddrVO.getAreaId())){
                return true;
            }else {
                return false;
            }
        }
    }
}
